package imgprocess;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;

public class Main {

    public Main() {
        //read Mat
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    public static String prefix = "E:/public/fuck/";


    public void write(Mat mat, String name) throws IOException{
        ImageIO.write((RenderedImage) HighGui.toBufferedImage(mat), "jpg", new File(prefix + name + "_processed"));
    }

    public String rename(String name){
        return name + "_processed";
    }


    public String blur(String name) throws IOException {
        Mat dst = new Mat();

        Mat mat = Imgcodecs.imread(Main.prefix + name, 1);

        Imgproc.medianBlur(mat, dst, 5);

        write(dst,name);

        return rename(name);
    }

    public String salt(String name, int num) throws IOException {
        Mat mat = Imgcodecs.imread(Main.prefix + name, 1);
        write(saltProc(mat,num),name);
//        ImageIO.write((RenderedImage) HighGui.toBufferedImage(saltProc(mat, num)), "jpg", new File(prefix + name + "_processed"));
        return rename(name);
    }

    public Mat saltProc(Mat mat, int num) {
        System.out.println(mat.type());
        Random rand = new Random();
        for (int i = 0; i < num; i++) {
            int r = rand.nextInt(mat.rows());
            int c = rand.nextInt(mat.cols());
            mat.put(r, c, 255, 255, 255);
        }
        return mat;
    }


    public String dilate(String name) throws IOException{
        return this.dilate(name, 100);
    }

    public String dilate(String name,int thresh) throws IOException{
        return this.dilate(name,thresh,5);
    }

    public String dilate(String name,int thresh,int size) throws IOException{
        return this.dilateAndErode("dilate",name,thresh,size);
    }

    public String erode(String name) throws IOException{
        return this.erode(name,100);
    }

    public String erode(String name, int thresh) throws IOException{
        return this.erode(name,thresh,5);
    }

    public String erode(String name,int thresh, int size) throws IOException{
        return this.dilateAndErode("erode",name,thresh,size);
    }


    public String dilateAndErode(String type , String name, int thresh, int size) throws IOException{
        Mat dst = new Mat();
        Mat thresholded = new Mat();

        Mat mat = Imgcodecs.imread(Main.prefix + name, 0);


        if(thresh < 10 || thresh > 245){
            System.out.println("Should not use thresh like " + thresh);
            thresh = 100;
        }

        Imgproc.threshold(mat,thresholded,thresh,255,0);

        if(size < 1 || size > 100){
            size = 5;
        }

        Mat kernel = Imgproc.getStructuringElement(Imgproc.CV_SHAPE_RECT,
                new Size(size,size));


        if(type.equals("erode")){
            Imgproc.erode(thresholded, dst, kernel);
        }else{
            Imgproc.dilate(thresholded, dst, kernel);
        }

        write(dst, name);
//        showImg(dst);
        return rename(name);
    }

    public String fudiao(String type,String name) throws IOException{
        Mat mat = Imgcodecs.imread(Main.prefix + name, 1);
        Mat dst = new Mat();
        if(type.equals("horizontal")){
            System.out.println("horizon");
            Imgproc.Sobel(mat,dst,-1,1,0,3,0.4,128);
        }else{
            System.out.println("vertical");
            Imgproc.Sobel(mat,dst,-1,0,1,3,0.4,128);
        }
        write(dst, name);
//        showImg(dst);
        return rename(name);
    }


    public static void showImg(Mat mat) {
        Image img = HighGui.toBufferedImage(mat);
        JPanel panel = new JPanel();

        JLabel label = new JLabel(new ImageIcon(img));
        panel.add(label);

        // main window
        JFrame.setDefaultLookAndFeelDecorated(true);
        JFrame frame = new JFrame("salt");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // add the Jpanel to the main window
        frame.add(panel);

        frame.pack();
        frame.setVisible(true);
    }
}
